import config from '@/config/index';
import { useI18n } from '@/hooks/web/useI18n';
import { store } from '@/store';
import { userStore } from '@/store/modules/walletUser';
import metaletUtils from '@/utils/wallet/metaletUtils';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { message, Modal } from 'ant-design-vue';
import Compressor from 'compressorjs';
import CryptoJs from 'crypto-js';
import encHex from 'crypto-js/enc-hex';
import { createVNode } from 'vue';
import * as metaidv2api from './metaidv2api';

type handleBuzzType = (item: any) => Promise<void>
type promiseType = (item: any) => Promise<any>
type voidType = () => Promise<void>
interface metaidv2Data {
	handleBuzz: handleBuzzType
	getBuzzLikeRefStatus: promiseType
	getBuzzCommentRefStatus: promiseType
	loginMetalet: voidType
	afterConnectedWallet: promiseType
	onLogout: any
	checkWalletIsLogin: voidType
	fileToAttachment: promiseType
	compressImage: promiseType
}
const metaidv2Utils = {} as metaidv2Data
const wUserStore = userStore(store)

metaidv2Utils.handleBuzz = async function (item) {
	let summary = item.contentSummary
	const isSummaryJson = summary.startsWith('{') && summary.endsWith('}')
	const parseSummary = isSummaryJson ? JSON.parse(summary) : {}
	summary = isSummaryJson ? parseSummary.content : summary

	item.summary = summary
	item.txid = item.id.substr(0, item.id.length - 2)
	const attachmentsPids = (parseSummary.attachments ?? []).map(
		(d) => d.split('metafile://')[1]
	)
	item.attachmentsPids = attachmentsPids
	item.quotePin = parseSummary.quotePin
	//引用的buzz
	if (parseSummary.quotePin) {
		const quoteBuzz:any = (await metaidv2api.queryOneBuzz(parseSummary.quotePin)) || {}
    const data = quoteBuzz.data || {}
		await this.handleBuzz(data)
		item.quoteBuzz = data
	}

	//获取metaid
	const metaidInfo: any = (await metaidv2api.getMetaidByAddress(item.address)) || {}
	if (!metaidInfo.name || metaidInfo.name.length == 0) {
		metaidInfo.name = metaidInfo?.metaid?.substr(0, 8)
	}
	//获取buzz的点赞数
	const likesCount = await this.getBuzzLikeRefStatus(item.id)
	//获取buzz的评论数
	const commentItem = await this.getBuzzCommentRefStatus(item.id)
	item.likesCount = likesCount
  // 合并item跟commentItem
	Object.assign(item, commentItem)
	item.metaidInfo = metaidInfo
}

metaidv2Utils.getBuzzLikeRefStatus = (id) => {
	return new Promise(async (resolve) => {
		const p = {
			collection: 'paylike',
			action: 'get',
			filterRelation: 'and',
			field: [],
			filter: [
				{
					operator: '=',
					key: 'likeTo',
					value: id
				}
			],
			cursor: 0,
			limit: 99999,
			sort: []
		}
		const res = await metaidv2api.generalQuery(p) as any
		if (res.data && res.data.length > 0) {
			resolve(res.data.length)
		} else {
			resolve(0)
		}
	})
}
metaidv2Utils.getBuzzCommentRefStatus = (id) => {
	return new Promise(async (resolve) => {
		const p = {
			collection: 'paycomment',
			action: 'get',
			filterRelation: 'and',
			field: [],
			filter: [
				{
					operator: '=',
					key: 'commentTo',
					value: id
				}
			],
			cursor: 0,
			limit: 99999,
			sort: ['number', 'desc']
		}
		const res = await metaidv2api.generalQuery(p) as any
		let item: any = {}
		if (res.data && res.data.length > 0) {
			item.commentCount = res.data.length
			item.commentList = []
			for (let i = 0; i < res.data.length; i++) {
				const comment = res.data[i]
				const commentBuzz:any = await metaidv2api.queryOneBuzz(comment.pinId) || {}
				await metaidv2Utils.handleBuzz(commentBuzz.data)
				item.commentList.push(commentBuzz.data)
			}
		}
		resolve(item)
	})
}

metaidv2Utils.loginMetalet = async () => {
	if (typeof window.metaidwallet == "undefined") {
		const { t } = useI18n()
		Modal.confirm({
			title: t("component.modal.title"),
			icon: createVNode(ExclamationCircleOutlined),
			content: t("component.metalet.downloadTip"),
			okText: t("component.modal.okText"),
			cancelText: t("component.modal.cancelText"),
			onOk() {
				window.open(
					"https://chromewebstore.google.com/search/metalet?hl=zh-CN&utm_source=ext_sidebar",
					"_blank"
				);
			},
			onCancel() { },
		});
		return;
	}
	const connectRes = await window.metaidwallet.connect();
	if (!connectRes?.address) {
		return;
	}
	await metaidv2Utils.afterConnectedWallet(connectRes.address);
}

function handleAcccountsChanged() {
	metaidv2Utils.onLogout()
	message.warning('wallet account changed,please login again')
}

function handleNetworkChanged() {
	metaidv2Utils.onLogout()
	message.warning('wallet network changed,please login again')
	setTimeout(() => {
		window.location.reload()
	}, 500)
}

/** 连接上钱包后操作 */
metaidv2Utils.afterConnectedWallet = async (address) => {
	window.metaidwallet.on("accountsChanged", handleAcccountsChanged);
	window.metaidwallet.on("networkChanged", handleNetworkChanged);
	//设置钱包工具类
	window.$walletUtils = metaletUtils;
	wUserStore.changeCurrentWallet(window.$walletUtils.getCurrentWallet());
	//检查metaid信息
	const metaidInfo = ((await metaidv2api.getMetaidByAddress(address)) || { data: {} }) as any;
	console.log("metaidInfo:", metaidInfo);
	if (!metaidInfo.data || !metaidInfo.data.name || metaidInfo.data.name.length == 0) {
		console.log("metaid name not exist");
	}

	wUserStore.changeUserInfoObj(metaidInfo.data);
	wUserStore.changeIsLogin(true);

	//this.$message.success(this.$t('views_login_350'))
	message.success('login success')
}

metaidv2Utils.checkWalletIsLogin = async () => {
	const isLastMangedLogined = lastLoginWalletIsManagedWallet()
	console.log('isLastMangedLogined', isLastMangedLogined)
	if (isLastMangedLogined) {
		return
	}
	if (!window.metaidwallet) {
		return
	}

	const connectedRes = await window.metaidwallet.isConnected()
	if (connectedRes) {
		const address = await window.metaidwallet.getAddress()
		await metaidv2Utils.afterConnectedWallet(address)
	}
}

function getLastLoginWallet() {
	return sessionStorage.getItem('lastLoginWallet')
}

function lastLoginWalletIsManagedWallet() {
	return config.managedWallet === getLastLoginWallet()
}
metaidv2Utils.onLogout = () => {
	//清理之前的登录信息
	wUserStore.changeIsLogin(false);
	wUserStore.changeUserInfoObj(null);
	sessionStorage.removeItem('lastLoginWallet')
	if (window.metaidwallet) {
		window.metaidwallet.removeListener('accountsChanged')
		window.metaidwallet.removeListener('networkChanged')
	}
}

metaidv2Utils.fileToAttachment = async (file) => {
	async function readResult(blob) {
		return new Promise((resolve) => {
			const reader = new FileReader()
			reader.onload = () => {
				// @ts-ignore
				const wordArray = CryptoJs.lib.WordArray.create(reader.result)
				// @ts-ignore
				const buffer = Buffer.from(reader.result)
				// console.log("buffer", buffer, reader.result);
				hex += buffer.toString('hex') // 更新hex
				// 增量更新计算结果
				sha256Algo.update(wordArray) // 更新hash
				resolve(reader)
			}
			reader.readAsArrayBuffer(blob)
		})
	}
	// 分块读取，防止内存溢出，这里设置为20MB,可以根据实际情况进行配置
	const chunkSize = 20 * 1024 * 1024

	let hex = '' // 二进制
	const sha256Algo = CryptoJs.algo.SHA256.create()

	for (let index = 0; index < file.size; index += chunkSize) {
		await readResult(file.slice(index, index + chunkSize))
	}
	return {
		data: hex,
		fileName: file.name,
		fileType: file.type,
		sha256: encHex.stringify(sha256Algo.finalize()),
		size: file.size
	}
}

metaidv2Utils.compressImage = async (image) => {
	const compress:any = (quality) =>
		new Promise((resolve, reject) => {
			new Compressor(image, {
				quality,
				convertSize: 100_000, // 100KB
				success: resolve,
				error: reject
			})
		})

	// Use 0.6 compression ratio first; If the result is still larger than 1MB, use half of the compression ratio; Repeat 5 times until the result is less than 1MB, otherwise raise an error
	let useQuality = 0.6
	for (let i = 0; i < 5; i++) {
		const compressed = await compress(useQuality)
		if (compressed.size < 1_000_000) {
			return compressed
		}
		useQuality /= 2
	}

	throw new Error('Image is too large')
}

export default metaidv2Utils
